package com.card.game;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import com.card.game.event.EventType;
import com.card.game.room.RoomSetting;
import com.card.game.room.SHRoom;
import com.card.timer.GameTimerManager;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.xiaoao.net.global.Global;
import com.xiaoao.net.json.message.JsonMessage;
import com.xiaoao.net.utils.StringUtil;

/**
 * @Description: TODO(用一句话描述该文件做什么)
 * @author siyunlong
 * @date 2016年8月24日 下午3:56:25
 * @version V1.0
 */
public class GameResult {
	protected boolean isLiuJu;
	protected boolean genZhuang;
	protected String nextZhuangId;
	// 是否有人胡了
	protected List<String> huList = Lists.newArrayList();
	protected List<String> tingList = Lists.newArrayList();
	protected String dianpaoId;
	protected String zimoId;

	protected transient Card huCard;
	protected transient Card zimoCard;
	protected transient EventType huType;
	protected transient Map<String, Integer> fanScoreMap = Maps.newConcurrentMap();
	protected transient Map<String, Integer> gangScoreMap = Maps.newConcurrentMap();
	protected transient Map<String, Integer> anScoreMap = Maps.newConcurrentMap();

	protected transient Map<String, Integer> otherScoreMap = Maps.newConcurrentMap();

	protected transient ArrayListMultimap<String, GangEvent> gangMap = ArrayListMultimap.create();
	protected transient List<GangEvent> anGangList = Lists.newArrayList();
	protected transient Map<String, String> showInfoMap = Maps.newConcurrentMap();

	protected transient SHRoom room;

	private ListMultimap<String, EventType> userEvent = ArrayListMultimap.create();

	public GameResult(SHRoom room) {
		this.room = room;
	}

	public boolean isLiuJu() {
		return isLiuJu;
	}

	public void setLiuJu(boolean isLiuJu) {
		this.isLiuJu = isLiuJu;
	}

	public boolean isZimo() {
		return zimoId != null;
	}

	public boolean isGenZhuang() {
		return genZhuang;
	}

	public void setGenZhuang(boolean genZhuang) {
		this.genZhuang = genZhuang;
	}

	public List<String> getHuList() {
		return huList;
	}

	public void endGame() {
		this.isLiuJu = false;
		this.genZhuang = false;
		this.huType = null;
		this.dianpaoId = null;
		this.zimoId = null;
		this.huCard = null;
		this.zimoCard = null;
		this.huList.clear();
		this.tingList.clear();
		this.gangMap.clear();
		this.anGangList.clear();
		this.fanScoreMap.clear();
		this.gangScoreMap.clear();
		this.otherScoreMap.clear();
		this.userEvent.clear();
		this.showInfoMap.clear();
		this.anScoreMap.clear();
	}

	public String getNextZhuangId() {
		return nextZhuangId;
	}

	public void addTingCard(String userId) {
		this.tingList.add(userId);
	}

	public int getFanScore(String userId) {
		if (fanScoreMap.containsKey(userId)) {
			return fanScoreMap.get(userId);
		}
		return 0;
	}

	private void addFanScore(String userId, int value) {
		int v = value;
		fanScoreMap.put(userId, getFanScore(userId) + v);
	}

	public int getOtherScore(String userId) {
		// if(otherScoreMap.containsKey(userId)) {
		// return otherScoreMap.get(userId);
		// }
		return 0;
	}

	public void addOtherScore(String userId, int value) {
		int v = value;
		otherScoreMap.put(userId, getOtherScore(userId) + v);
	}

	public int getGangScore(String userId) {
		if (gangScoreMap.containsKey(userId)) {
			return gangScoreMap.get(userId);
		}
		return 0;
	}

	public void addGangScore(String userId, int value) {
		gangScoreMap.put(userId, getGangScore(userId) + value);
	}

	private int getAnGangScore(String userId) {
		if (anScoreMap.containsKey(userId)) {
			return anScoreMap.get(userId);
		}
		return 0;
	}

	public List<EventType> getEventType(String userId) {
		return userEvent.get(userId);
	}

	public void addEvent(String userId, EventType type) {
		userEvent.put(userId, type);
	}

	// 计算暗杠分
	public void calAnGangScore(String userId, int score) {
		addEvent(userId, EventType.AnGang);
		RoomSetting roomSetting = room.getRoomSetting();
		Player player = room.getPlayerById(userId);
		for (BasePlayer temp : room.getPlayerList()) {
			int AnGangScore = score;
			if (StringUtil.equals(temp.getUserId(), userId)) {
				continue;
			}
			Player temp1 = (Player) temp;
			if ((room.isZhuang(userId) || room.isZhuang(temp1.getUserId())) && roomSetting.isZhuangJiadi()) {
				AnGangScore += 1;
			}
			// if (roomSetting.isGangpao()) {
			// AnGangScore += (player.jiaBei + temp1.jiaBei);
			// }

			addGangScore(userId, AnGangScore);
			addGangScore(temp1.getUserId(), -AnGangScore);
			// anScoreMap.put(userId, getAnGangScore(userId) + score);
		}
	}

	public void calFangGangScore(Player player, String gangId, int score) {
		// System.out.println("calFangGangScore");
		String userId = player.getUserId();
		Player gangPlayer = room.getPlayerById(gangId);
		RoomSetting roomSetting = room.getRoomSetting();

		addEvent(userId, EventType.FangGang);
		addEvent(gangId, EventType.DianGang);

		int GangScore = 1;

		if ((room.isZhuang(userId) || room.isZhuang(gangId)) && roomSetting.isZhuangJiadi()) {
			GangScore += 1;
		}
		// if (roomSetting.isGangpao()) {
		// GangScore += (player.jiaBei + gangPlayer.jiaBei);
		// }
		// System.out.println("GangScore:" + GangScore);
		addGangScore(userId, GangScore);
		addGangScore(gangId, -GangScore);
	}

	public void calGuoLuGangScore(Player player, String gangId, int score) {
		String userId = player.getUserId();
		int AnGangScore = 1;
		if (room.isHZRoom()) {
			addEvent(userId, EventType.GuoLuGang);
			addGangScore(userId, AnGangScore * 3);
			for (BasePlayer temp : room.getPlayerList()) {
				if (!StringUtil.equals(temp.getUserId(), userId)) {
					addGangScore(temp.getUserId(), -AnGangScore);
				}
			}
		} else {
			addEvent(userId, EventType.GuoLuGang);
			addEvent(gangId, EventType.DianGang);
			addGangScore(userId, score + 2);
		}
	}

	// 点炮胡算分
	public void calDianPaoScore(String userId, String dianpaoId, EventType type) {
		System.out.println("点炮胡算分");
		RoomSetting roomSetting = room.getRoomSetting();
		Player player = room.getPlayerById(userId);
		Player dpPlayer = room.getPlayerById(dianpaoId);
		int di = 1;
		di += ((room.isZhuang(userId) || room.isZhuang(dianpaoId)) && roomSetting.isZhuangJiadi()) ? 1 : 0;

		// if (roomSetting.isHasPao()) {
		// di += player.jiaBei + dpPlayer.jiaBei;
		// }
		int bei = getHuScore(player, type);

		addFanScore(userId, di * bei);
		addFanScore(dianpaoId, -di * bei);
	}

	// 自摸胡算分
	public void cal3Score(String userId, int bei) {
		// System.out.println("自摸胡算分");
		RoomSetting roomSetting = room.getRoomSetting();
		Player winPlayer = room.getPlayerById(userId);
		Iterator<BasePlayer> it = room.getPlayerList().iterator();
		while (it.hasNext()) {
			Player temp = (Player) it.next();
			if (!StringUtil.equals(temp.getUserId(), getWinId())) {
				int di = 1;
				di += ((room.isZhuang(userId) || room.isZhuang(temp.getUserId())) && roomSetting.isZhuangJiadi()) ? 1
						: 0;
				if (roomSetting.isHasPao()) {
					di += winPlayer.jiaBei + temp.jiaBei;
				}
				String msg = getShowInfo(userId);
				this.showInfoMap.put(userId, msg);
				addFanScore(userId, di * bei);
				addFanScore(temp.getUserId(), -di * bei);
			}
		}
	}

	public void calZiMoScore(String userId, EventType eventType) {
		// if (room.isHZRoom()) {
		// calHZZiMoScore(userId, EventType.ZiMo);
		// return;
		// }
		this.zimoId = userId;
		this.huList.add(userId);
		addEvent(userId, eventType);
		Player player = room.getPlayerById(userId);
		this.zimoCard = player.getLastInCard();
		StringBuilder showInfo = new StringBuilder();
		this.showInfoMap.put(userId, showInfo.toString());
		// this.gangScoreMap.clear();
		int bei = getHuScore(player, eventType);
		cal3Score(userId, bei);
	}

	public void calHuScore(String userId, String dianPaoId, Card outCard, EventType type) {
		// if (room.isHZRoom()) {
		// calHZHuScore(userId, dianPaoId, outCard, type);
		// return;
		// }
		this.huList.add(userId);
		this.dianpaoId = dianPaoId;
		this.huCard = outCard;
		this.huType = type;
	}

	// 获取单人分数
	public int getHuScore(Player player, EventType type) {
		// System.out.println("获取单人分数");
		int fen = 1;
		String paiString = "";
		if (type == EventType.GangTouKaiHua) {
			paiString += "杠上开花,";
			fen *= 2;
			if (room.curEvent.getGangType() == EventType.DianGang) {
				calFangGangScore(player, room.lastOutCardUser, 1);
			} else {
				calAnGangScore(player.getUserId(), 1);
			}
		}

		Vector<Card> cards = (Vector<Card>) player.getHand().cards.clone();
		if (isZimo()) {
			cards.remove(huCard);
		}
		Vector<Card> clones = (Vector<Card>) cards.clone();
		clones.add(huCard);
		// 根据牌型判断倍数
		boolean isNoTianHu = true;
		boolean isTianHu = player.isTianHu();
		boolean isMenQing = player.isMenQing();
		boolean isDuiDuiHu = AqUtils.isDuiDuiHu(player, cards, huCard);
		boolean isQYS = AqUtils.isQingYiSe(player, cards, huCard);
		boolean isLong = AqUtils.isYiTiaoLong(player, cards, huCard);
		boolean is7Dui = HandUtils.allIsDui(cards);
		System.out.println(cards); // 14张牌
		System.out.println(clones); // 14张牌+null
		if (isTianHu) {
			fen *= 2;
			paiString += "天胡,";
		}
		if (isDuiDuiHu) {
			fen *= 2;
			paiString += "对对胡,";

		}
		if (is7Dui) {
			int size = CardUtils.findSameCardBySize(cards, 4).size();
			if (size == 0) {
				paiString += "七对,";
				fen *= 3;
			} else if (size == 1) {
				paiString += "豪华七对,";
				fen *= 5;
			} else if (size >= 2) {
				paiString += "超豪华七对,";
				fen *= 10;
			}
			if (isMenQing) {
				fen *= 1;
				paiString += "门清,";
			}
		} else {
			if (isMenQing) {
				fen *= 2;
				paiString += "门清,";
			}
		}
		if (isQYS) {
			paiString += "清一色,";
			fen *= 4;
		}
		if (isLong) {
			paiString += "一条龙,";
			fen *= 3;
		}
		// if (fen == 0) {
		// fen = 1;
		// }
		if (room.getRoomSetting().getMaima() > 0) {
			int ma = room.calMa();
			paiString += ma + "马,";
			fen += ma;
		}
		System.out.println(paiString + fen + "分");
		return fen;
	}

	public void calHZHuScore(String userId, String dianPaoId, Card outCard, EventType type) {
		this.huList.add(userId);
		this.dianpaoId = dianPaoId;
		this.huCard = outCard;
		Player player = room.getPlayerById(userId);
		Vector<Card> clones = (Vector<Card>) player.getHand().cards.clone();
		clones.add(outCard);
		int score = getHZScore(player, clones);
		addFanScore(userId, score * 3);
		addFanScore(dianPaoId, -score * 3);
	}

	public void calHZZiMoScore(String userId, EventType eventType) {
		this.zimoId = userId;
		this.huList.add(userId);
		addEvent(userId, eventType);
		Player player = room.getPlayerById(userId);
		this.zimoCard = player.getLastInCard();
		Vector<Card> clones = (Vector<Card>) player.getHand().cards.clone();
		int score = getHZScore(player, clones);
		score += room.getNiaoScore();
		addFanScore(userId, score * 3);
		for (BasePlayer temp : room.getPlayerList()) {
			if (!StringUtil.equals(temp.getUserId(), userId)) {
				addFanScore(temp.getUserId(), -score);
			}
		}
		this.showInfoMap.put(userId, "自摸胡  ");
	}

	public int getHZScore(Player player, Vector<Card> clones) {
		int score = 5;
		if (player.isHZMenQing()) {
			score += 1;
		}
		int hzNum = HZUtils.getHZCardNum(clones);
		if (hzNum == 1) {
			score += 1;
		}
		if (hzNum == 4) {
			score += 7;
		}
		if (HandUtils.allIsDui(clones)) {
			score += 1;
		}
		return score;
	}

	public String getWinId() {
		if (isLiuJu) {
			return null;
		}
		if (isZimo()) {
			return zimoId;
		}
		return huList.get(0);
	}

	public void calResult() {
		Global.logErrorMessage(tingList.toString());
		if (isLiuJu) {
			this.nextZhuangId = room.getZhuangId();
		} else {
			if (!isZimo() && huList.size() > 1) {
				Player nextPlayer = room.getPlayerById(dianpaoId);
				this.nextZhuangId = nextPlayer.getUserId();
			} else {
				Player nextPlayer = room.getPlayerById(getWinId());
				this.nextZhuangId = nextPlayer.getUserId();
			}
		}
		if (isLiuJu) {
			fanScoreMap.clear();
			gangScoreMap.clear();
			otherScoreMap.clear();
			userEvent.clear();
			return;
		}
		if (!room.isHZRoom()) {
			if (!isZimo()) {
				this.showInfoMap.put(dianpaoId, "点炮");
				for (String userId : huList) {
					StringBuilder showInfo = new StringBuilder();
					calDianPaoScore(userId, dianpaoId, huType);
					this.showInfoMap.put(userId, showInfo.toString());
				}
			}
			// this.gangScoreMap.clear();
		} else {
			Player winPlayer = room.getPlayerById(getWinId());
			calZiMoScore(getWinId(), huType);
			// this.showInfoMap.put(userId, info.toString());
			String winUserId = getWinId();
			this.nextZhuangId = winUserId;
		}
	}

	public void fillMsg(JsonMessage message) {
		message.addProperty("isLiuJu", isLiuJu);
		message.addProperty("genZhuang", genZhuang);
	}

	// =========================================================

	public int getBaoPaiScore(Player winPlayer, Player temp) {
		if (winPlayer.isBaoPai(temp.getUserId())) {
			return 5;
		}
		if (temp.isBaoPai(winPlayer.getUserId())) {
			return 10;
		}
		return 0;
	}

	public int getEventNum(String userId, EventType type) {
		int num = 0;
		for (EventType e : userEvent.get(userId)) {
			if (type.equals(e)) {
				num++;
			}
		}
		return num;
	}

	public String getShowInfo(String userId) {
		if (this.showInfoMap.containsKey(userId)) {
			return this.showInfoMap.get(userId);
		}
		return "";
	}

	public String getZimoId() {
		return zimoId;
	}

	public boolean isHu(String userId) {
		return huList.contains(userId);
	}

	public boolean isWinUser(String userId) {
		return huList.contains(userId);
	}

	public boolean isDianPaoUser(String userId) {
		return StringUtil.equals(userId, dianpaoId);
	}

}
